use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};
use uuid::Uuid;

/// 消息类型枚举
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MessageType {
    Register,
    Heartbeat,
    Command,
    CommandResult,
    FileTransfer,
    FileTransferResult,
    Response,
    Error,
}

/// 基础消息结构
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Message {
    pub id: Uuid,
    pub message_type: MessageType,
    pub timestamp: DateTime<Utc>,
    pub payload: MessagePayload,
}

/// 消息载荷
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum MessagePayload {
    Register(RegisterMessage),
    Heartbeat(HeartbeatMessage),
    Command(CommandMessage),
    CommandResult(CommandResultMessage),
    FileTransfer(FileTransferMessage),
    FileTransferResult(FileTransferResultMessage),
    Response(ResponseMessage),
    Error(ErrorMessage),
}

/// 注册消息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RegisterMessage {
    pub id: String,
    pub hostname: String,
    pub ip: String,
    pub tags: Vec<String>,
    pub version: String,
}

/// 心跳消息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HeartbeatMessage {
    pub id: String,
    pub hostname: String,
    pub status: NodeStatus,
    pub load: SystemLoad,
    pub errors: Vec<String>,
}

/// 节点状态
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NodeStatus {
    pub cpu_usage: f64,
    pub memory_usage: f64,
    pub disk_usage: f64,
    pub uptime: u64,
}

/// 系统负载
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemLoad {
    pub load_1: f64,
    pub load_5: f64,
    pub load_15: f64,
}

/// 命令消息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommandMessage {
    pub command_id: Uuid,
    pub command_type: CommandType,
    pub target_groups: Vec<String>,
    pub timeout: u64,
}

/// 命令类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CommandType {
    Shell(String),
    Script(String),
    ServiceRestart(String),
    FileOperation(FileOperation),
}

/// 文件操作
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileOperation {
    pub operation: String, // "copy", "delete", "chmod"
    pub source: String,
    pub destination: String,
    pub permissions: Option<u32>,
}

/// 命令结果消息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommandResultMessage {
    pub command_id: Uuid,
    pub hostname: String,
    pub success: bool,
    pub exit_code: i32,
    pub stdout: String,
    pub stderr: String,
    pub execution_time: u64,
}

/// 文件传输消息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileTransferMessage {
    pub file_id: Uuid,
    pub filename: String,
    pub size: u64,
    pub checksum: String,
    pub chunk_size: usize,
    pub target_groups: Vec<String>,
}

/// 文件传输结果消息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileTransferResultMessage {
    pub file_id: Uuid,
    pub hostname: String,
    pub success: bool,
    pub received_size: u64,
    pub checksum_verified: bool,
    pub error_message: Option<String>,
}

/// 响应消息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResponseMessage {
    pub success: bool,
    pub message: String,
    pub data: Option<serde_json::Value>,
}

/// 错误消息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ErrorMessage {
    pub code: String,
    pub message: String,
    pub details: Option<String>,
}

impl Message {
    pub fn new(message_type: MessageType, payload: MessagePayload) -> Self {
        Self {
            id: Uuid::new_v4(),
            message_type,
            timestamp: Utc::now(),
            payload,
        }
    }

    pub fn register(id: String, hostname: String, ip: String, tags: Vec<String>, version: String) -> Self {
        Self::new(
            MessageType::Register,
            MessagePayload::Register(RegisterMessage {
                id,
                hostname,
                ip,
                tags,
                version,
            }),
        )
    }

    pub fn heartbeat(id: String, hostname: String, status: NodeStatus, load: SystemLoad, errors: Vec<String>) -> Self {
        Self::new(
            MessageType::Heartbeat,
            MessagePayload::Heartbeat(HeartbeatMessage {
                id,
                hostname,
                status,
                load,
                errors,
            }),
        )
    }

    pub fn command(command_id: Uuid, command_type: CommandType, target_groups: Vec<String>, timeout: u64) -> Self {
        Self::new(
            MessageType::Command,
            MessagePayload::Command(CommandMessage {
                command_id,
                command_type,
                target_groups,
                timeout,
            }),
        )
    }

    pub fn command_result(command_id: Uuid, hostname: String, success: bool, exit_code: i32, stdout: String, stderr: String, execution_time: u64) -> Self {
        Self::new(
            MessageType::CommandResult,
            MessagePayload::CommandResult(CommandResultMessage {
                command_id,
                hostname,
                success,
                exit_code,
                stdout,
                stderr,
                execution_time,
            }),
        )
    }

    pub fn response(success: bool, message: String, data: Option<serde_json::Value>) -> Self {
        Self::new(
            MessageType::Response,
            MessagePayload::Response(ResponseMessage {
                success,
                message,
                data,
            }),
        )
    }

    pub fn error(code: String, message: String, details: Option<String>) -> Self {
        Self::new(
            MessageType::Error,
            MessagePayload::Error(ErrorMessage {
                code,
                message,
                details,
            }),
        )
    }
} 